// 不可变引用的参数的生命周期，'a与函数的存活时间相同，即函数的生命周期与参数的生命周期相同。
fn print_one<'a>(x: &'a i32) {
    println!("x is {}", x);
}

// 可变引用的生命周期也一样
fn add_one<'a>(x: &'a mut i32) {
    *x += 1;
}

// 两个不同的生命周期参数
fn print_multi<'a,'b>(x: &'a i32, y: &'b i32) {
    println!("x is {}, y is {}", x, y);
}

// 要返回正确的生命周期，与返回值约束匹配
fn  pass_x<'a,'b>(x: &'a  i32, _: &'b i32) -> &'a i32 {
    x
}


// 注意：
// 1. 生命周期参数的顺序要与函数声明中的参数顺序一致。
// 2. 生命周期参数的约束，要与函数声明中的约束一致。
// 3. 生命周期参数的返回值，要与函数声明中的返回值一致。
fn main() {
    let x = 7;
    let y = 9;

    // 看来引用与Java中的引用意义是相同的
    print_one(&x);
    print_multi(&x, &y);

    let mut z = 5;
    add_one(&mut z);
    print_one(&z);

    let a = 5;
    let b = 8;
    let c = pass_x(&a, &b);
    print_one(c);
}
